/* 
 * jQuery.jCutter.js v0.0.21
 * 
 * @作者 : czb
 * @创建时间: 2015.09.13 09:35PRC
 * @EMail：398061026@qq.com
 * @修改时间：2015.10.07 18:23PRC
 * 
 * @更新日志：
 *    v0.0.2：
 *      1，v0.0.1不支持创建完成后再配置插件，v0.0.2修改代码以使插件可以再插件创建完成后通过
 *           $(...).jCutter()函数更改插件的参数；（这显然是本人能力所致，因为我是第一次开发jQuery插件，相信大家可以原谅^_^）
 *      2，其他代码上的优化。
 *    v0.0.21：
 *      更改插件存储配置信息的方式以适应多个插件同时运行时的错误。
 * @下一版本看点：
 *    1，增加滑动条缩放图片；
 *    2，指定将图片缩放至某一尺寸；
 *    
 * @遗留问题：
 *     在FF浏览器下，滚轮事件的冒泡行为不能停止，导致原本的滚轮缩放行为会冒泡至body导致页面滚动（如果可以），请
 *     高手不吝赐教，联系作者EMail并阐述解决方法。不甚感激。
 *     
 * @注：请使用本插件的程序猿sir不惜麻烦，在您使用插件的页面上截个图发给作者的EMail（标题就写jcutter.user），满足
 *          一下作者的虚荣心^_^，您的支持就是小猿继续完善插件的动力，谢谢您的慷慨；
 *          
 *          使用方法请参考【说明.txt】文档。
 *           
 * 请使用本插件的程序猿sir不要删除此段说明文字，谢谢合作。
 */


(function($){
    var nextId = 1;
    $.jCutter = function(obj, opt){
        var options = $.extend(true,{},$.jCutter.defaults,$.jCutter.fixedDefaults),
              _ua = navigator.userAgent.toLowerCase(),
              is_msie = /msie/.test(_ua),//IE模式
              ie6mode = /msie [1-6]\./.test(_ua);//IE1-6模式
              //
        var src_img = null,
              cut_frame = null,
              container = null,
              cut_shift_left = 0,
              cut_shift_top = 0;
        //通用内部函数 - 开始
        function myClass(cl){//class
            return options.baseClass + '-' + cl;
        }
        function myJClass(cl){//.class
            return '.' + options.baseClass + '-' + cl;
        }
        function myId(id){
            return options.baseId + '_' + id;
        }
        function myJId(id){
            return '#' + options.baseId + '_' + id;
        }
        function err(msg){
            return {err:msg};
        }
        function getCutInfo(){
            return {
                'x': cut_frame.offset().left - src_img.offset().left + cut_shift_left,
                'y': cut_frame.offset().top - src_img.offset().top + cut_shift_top,
                'width': src_img.width(),
                'height': src_img.height(),
                'cutWidth': cut_frame.width(),
                'cutHeight': cut_frame.height()
            };
        }
        function _cutChange(){
            if($.isFunction(options.cutChange)){
                var c = getCutInfo();
                options.cutChange.call(this,c);
            }
        }
        function setOptions(){
            var chk = checkOptions();
            if(chk !== true){
                return chk;
            }
            options = $.extend(true,{}, options, opt, $.jCutter.fixedDefaults);
            return true;
        }
        function setOptionsNew(opt){
            var chk = checkOptions();
            if(chk !== true){
                return chk;
            }
            options = $.extend(true,{}, options, opt, $.jCutter.fixedDefaults);
            var chk = applyOptions();
            if(options.limitEdge){
                BorderLimiter.check();
            }
        }
        function setCutFrameShade(set){
            var cf = $(myJClass('cut-frame'));
            set ? cf.css('boxShadow',options.cutCss.boxShadow) : cf.css('boxShadow','');
        }
        /**
         * 应用目标的样式信息，如果需要，通过动画执行。注：通过使用同一的执行函数收集对象的信息变化
         * @param {$object} target 应用样式的对象
         * @param {object} prop 样式信息
         * @param {boolean} e_q 如果正在执行动画，是否完成未完成的样式
         * @param {function} callback 回调函数
         * @param {object} args 参数
         * @param {integer} delay 执行动画的时长。注：如果该值不满足条件即认定为不执行动画，否则执行动画
         * @returns 无
         */
        function applyCss(target,prop,e_q,callback,args,delay){
            target.stop(true,e_q);
            if(delay && $.isNumeric(delay) && 0 < delay/* && delay <= 1000*/){
                target.animate(prop,delay,function(){
                    if($.isFunction(callback)){
                        callback.call(target,args);
                    }
                    _cutChange();
                });
            }
            else{
                target.css(prop);
                if($.isFunction(callback)){
                    callback.call(target,args);
                }                
                _cutChange();
            }
        }
//通用内部函数 - 结束

//鼠标模块 - 开始
//描述：在指定的目标（target）上监听鼠标的各种事件
        var Mouser = (function(){//target是jQuery对象
            var in_target = false,//鼠标在目标区域中
                  md_in_target = false,//鼠标在目标区域中按下
                  target = null,//监视对象
                  def_opt = {//默认设置
                    mouseLeftDown: function(){},//鼠标左键弹下回调函数
                    mouseLeftUp: function(){},//鼠标左键按开回调函数
                    mouseMiddleDown: function(){},//鼠标中键弹下回调函数
                    mouseMiddleUp: function(){},//鼠标中键按开回调函数
                    mouseRightDown: function(){},//鼠标右键弹下回调函数
                    mouseRightUp: function(){},//鼠标右键按开回调函数
                    wheelScrollUp: function(){},//鼠标滚轮上滚回调函数
                    wheelScrollDown: function(){},//鼠标滚轮下滚回调函数
                    wheelScroll: function(){}//鼠标滚轮滚动回调函数
            };
            $(document)
                    .bind('mouseup',mUp);
            function listen(tgt,options){
                return setTarget(tgt,options);
            }
            function unlisten(){
                target.unbind([
                    'mouseLeftDown',
                    'mouseLeftUp',
                    'mouseMiddleDown',
                    'mouseMiddleUp',
                    'mouseRightDown',
                    'mouseRightUp',
                    'wheelScrollUp',
                    'wheelScrollDown',
                    'wheelScroll',
                    'mousedown',
                    'mousewheel',
                    'mouseover',
                    'mouseout',
                    'blur']);
                if(target[0].removeEventListener){//Firefox mousewheel
                    target[0].removeEventListener('DOMMouseScroll');
                }
                return true;
            }
            function setTarget(tgt,options){
                if(!tgt){
                    return false;
                }
                target = tgt;
                var inTarget = function(){
                    in_target = true;
                };
                var notInTarget = function(){
                    in_target = false;
                };
                target
                    .bind(options)
                    .bind('mousedown',mDown)
                    .bind('mousewheel',mWheel)
                    .bind('mouseover',inTarget)
                    .bind('mouseout',notInTarget)
                    .bind('blur',function(){md_in_target = false;});//失去焦点，使鼠标在窗口内的点下操作失效
                if(target[0].addEventListener){//Firefox mousewheel
                    target[0].addEventListener('DOMMouseScroll',mWheel,false);
                }
                setOptions(options);
                return true;                
            }
            function setOptions(opt){
                def_opt = $.extend(def_opt,opt);
            }
            function setCursor(csr){
                target.css('cursor',csr);
            }
            function point(x,y){
                this.x = x;
                this.y = y;    
            }
            function mPoint(x,y){
                return new point(x,y);
            }
            function mPos(e){
                var x = parseFloat(e.pageX);
                var y = parseFloat(e.pageY);
                return new mPoint(x,y);
            }
            function mOffset(target,e){//获得鼠标的漂移值，如果有多个对象则按顺序封装成数组
                e = e  || window.event;
                var arr = [];
                for(var i=0;i<target.length;i++){
                    var mousePos = mPos(e);
                    var x = mousePos.x - target[i].offsetLeft;
                    var y = mousePos.y - target[i].offsetTop;
                    arr.push(new mPoint(x,y));
                }
                return arr;
            }
            function mInTarget(){
                return in_target;
            }
            function mDownInTarget(){
                return md_in_target;
            }
            function mUp(e){
                if(mDownInTarget()){
                    switch(e.which){
                        case 1:
                            if($.isFunction(def_opt.mouseLeftUp)) def_opt.mouseLeftUp.call(this,e);
                            break;
                        case 2:
                            if($.isFunction(def_opt.mouseMiddleUp)) def_opt.mouseMiddleUp.call(this,e);
                            break;
                        case 3:
                            if($.isFunction(def_opt.mouseRightUp)) def_opt.mouseRightUp.call(this,e);
                            break;
                    }
                    return false;
                }
                md_in_target = false;
            }        
            function mDown(e){
                if(mInTarget()){
                    md_in_target = true;
                    switch(e.which){
                        case 1:
                            if($.isFunction(def_opt.mouseLeftDown)) def_opt.mouseLeftDown.call(this,e);
                            break;
                        case 2:
                            if($.isFunction(def_opt.mouseMiddleDown)) def_opt.mouseMiddleDown.call(this,e);
                            break;
                        case 3:
                            if($.isFunction(def_opt.mouseRightDown)) def_opt.mouseRightDown.call(this,e);
                            break;
                    }
                    return false;
                }
            }
            function mWheel(e){
                if(mInTarget()){
                    var wheelDirection = e.originalEvent ? e.originalEvent.wheelDelta : -e.detail;//兼容Firefox
                    e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
                    var direction = wheelDirection > 0 ? 1 : -1;
                    if($.isFunction(def_opt.mouseWheel)) def_opt.mouseWheel.call(this,e,direction);
                    if(wheelDirection > 0){
                        if($.isFunction(def_opt.mouseWheelUp)){ 
                            def_opt.mouseWheelUp.call(this,e);
                            e.preventDefault();
                        }
                    }
                    else{
                        if($.isFunction(def_opt.mouseWheelDown)){
                            def_opt.mouseWheelDown.call(this,e);
                            e.preventDefault();
                        }
                    }
                    return false;
                }
            }
            return {
                listen:listen,
                unlisten: unlisten,
                mOffset:mOffset,
                mPos:mPos,
                setOptions: setOptions,
                setCursor: setCursor
            };
        }());
//鼠标模块 - 结束

//拖拽模块 - 开始
//描述：在指定的平台（panel）上通过鼠标拖拽指定目标（target）
        var Dragger = (function(){
            var target = null,
                  dragging = false,//保留
                  mouseOffset,
                  panel = null,
                  def_opt = {
                      dragStart:function(){},
                      dragging:function(){},
                      dragEnd:function(){}
                  };
            function listen(tgt,pn,opt){
                if(!tgt || !pn)
                    return false;
                target = tgt;
                panel = pn;
                pn.setOptions({
                    mouseLeftDown:function(e){
                        $(document).bind('mousemove',drag);
                        _dragStart(e);
                    },
                    mouseLeftUp:function(e){
                        $(document).unbind('mousemove');
                        _dragEnd(e);
                    }
                });                
                target
                        .css('position','absolute');
                setOptions(opt);
            }
            function setOptions(opt){
                def_opt = $.extend(def_opt,opt);
            }
            function _dragStart(e){
                mouseOffset = panel.mOffset(target,e);
                $(document)
                        .bind('selectstart',function(){return false;})
                        .bind('dragstart',function(){return false;})
                        .css('cursor','move');
                document.body.style.cursor = 'move';
                if($.isFunction(def_opt.dragStart)) def_opt.dragStart.call(e);
                dragging = true;
            }
            function _dragEnd(e){
                $(document)
                        .unbind('selectstart')
                        .unbind('dragstart')
                        .removeProp('cursor');
                document.body.style.cursor = 'default';
                if($.isFunction(def_opt.dragEnd)) def_opt.dragEnd.call(e);
                dragging = false;
            }
            function drag(e){
                var mp = panel.mPos(e);
                target.each(function(i){
                    var t_css = {
                        left:mp.x - mouseOffset[i].x,
                        top:mp.y - mouseOffset[i].y
                    };
                    $(this).css(t_css);
                });
                var t_css = {
                        left:mp.x - mouseOffset.x,
                        top:mp.y - mouseOffset.y
                };
                applyCss(target,t_css,true,def_opt.dragging,e);
            }
            return {
                listen:listen,
                setOptions:setOptions
            };
        }());
//拖拽模块 - 结束

//缩放模块 - 开始
//描述：在指定平台（panel）上通过鼠标滚轮事件缩放指定目标（target）
        var Zoomer = (function(){
            var target = null,
                  panel = null,
                  def_opt = {
                      zoomEnd:function(){},
                      zoomDelay:100
                  };
            function listen(tgt,pn,opt){
                if(!tgt || !pn){
                    return false;
                }
                target = tgt;
                panel = pn;
                panel.setOptions({
                    mouseWheel: zoom
                });
                setOptions(opt);
            }
            function setOptions(opt){
                def_opt = $.extend(def_opt,opt);
            }
            function zoom(e,direction){
                if($.isEmptyObject(target.attr('src'))){
                    return false;
                }
                e = e || window.event;
                var mo = panel.mPos(e);
                var width = target.width();
                var height = target.height();
                var t_offset = target.offset();
                //缩放中心为鼠标位置
                var offset_left = (t_offset.left - mo.x) * options.zoomPercent * direction;
                var offset_top = (t_offset.top - mo.y) * options.zoomPercent * direction;
                //缩放中心为图片中心****保留****
                var step_left = width / 2 * options.zoomPercent * -direction;
                var step_top = height / 2 * options.zoomPercent * -direction;
                //缩放的宽度，始终通过改变宽度来缩放图片保证图片的长宽比
                var step_width = width * options.zoomPercent * direction;
                var prop = {
                   'left': '+=' + offset_left + 'px',
                    'top': '+=' + offset_top + 'px',
                    'width': '+=' + step_width + 'px'
                };
                zoomTo(e,prop);
            }
            function zoomTo(e,prop){
                applyCss(target,prop,false,def_opt.zoomEnd,e,def_opt.zoomDelay);
            }
            return {
                listen: listen,
                setOptions: setOptions,
                zoomTo: zoomTo
            };
        }());
//缩放模块 - 结束
//触摸模块 - 开始
//描述：在指定平台（panel）上通过鼠触摸事件缩放或移动指定目标（target）（触屏手机平台，如安卓）
        var Toucher = (function(){
            var target = null,
                  panel = null,
                  touchOffset,
                  def_opt = {
                      moveEnd:function(){},
                      zoomEnd:function(){},
                      zoomDelay:100
                  };
            function listen(tgt,pn,opt){
                if(!tgt || !pn){
                    return false;
                }
                target = tgt;
                panel = pn;
                $(document)// czb 2015年10月7日21:59:51 czb_mark
                        .bind('touchstart',function(e){
                            touchOffset = {
                                'x' : e.touches[0].pageX,
                                'y' : e.touches[0].pageY
                            };
                            alert('x: ' + touchOffset.x + 'px , y: ' + touchOffset.y + ' px');
                        })
                        .bind('touchend',function(e){})
                        .bind('touchmove',function(e){
                            var t_css = {
                                'left' : e.touches[0].pageX - touchOffset.x,
                                'top' : e.touches[0].pageY - touchOffset.y
                            };
                            alert('left: ' + t_css.left + ' px, top:' + t_css.top + ' px');
                            moveTo(target,t_css);
                        })
                        .bind('gesturechange',function(e){});
                setOptions(opt);
            }
            function setOptions(opt){
                def_opt = $.extend(def_opt,opt);
            }
            function zoom(e,direction){
                if($.isEmptyObject(target.attr('src'))){
                    return false;
                }
                e = e || window.event;
                var mo = panel.mPos(e);
                var width = target.width();
                var height = target.height();
                var t_offset = target.offset();
                //缩放中心为鼠标位置
                var offset_left = (t_offset.left - mo.x) * def_opt.zoomPercent * direction;
                var offset_top = (t_offset.top - mo.y) * def_opt.zoomPercent * direction;
                //缩放中心为图片中心****保留****
                var step_left = width / 2 * def_opt.zoomPercent * -direction;
                var step_top = height / 2 * def_opt.zoomPercent * -direction;
                //缩放的宽度，始终通过改变宽度来缩放图片保证图片的长宽比
                var step_width = width * def_opt.zoomPercent * direction;
                var prop = {
                   'left': '+=' + offset_left + 'px',
                    'top': '+=' + offset_top + 'px',
                    'width': '+=' + step_width + 'px'
                };
                zoomTo(e,prop);
            }
            function zoomTo(e,prop){
                applyCss(target,prop,false,def_opt.zoomEnd,e,def_opt.zoomDelay);
            }
            function moveTo(e,prop){
                applyCss(target,prop,false,def_opt.moveEnd,e);
            }
            return {
                listen: listen,
                setOptions: setOptions,
                zoomTo: zoomTo,
                moveTo: moveTo
            };
        }());
//触摸模块 - 结束

//边缘限制模块 - 开始
//描述：在指定容器（tareget_container）内，限制目标（target）与限制层（limiter）的位置关系
        var BorderLimiter = (function(){
            var target = null,
                  target_container = null,
                  limiter = null,
                  def_opt = {
                      limitDelay:100
                  };
            function listen(tgt,lmtr,tgt_con,opt){
                if(!tgt || !lmtr || !tgt_con){
                    return false;
                }
                target = tgt;
                limiter = lmtr;
                target_container = tgt_con;
                setOptions(opt);
            }
            function unlisten(){
                target = null;
                limiter = null;
                target_container = null;
            }
            function setOptions(opt){
                def_opt = $.extend(def_opt,opt);
            }
            function ajust(prop){
                applyCss(target,prop,true,null,null,def_opt.limitDelay);
            }
            function check(){
                checkEdge(checkSize());
            }
            function checkEdge(p_zoom){
                if($.isEmptyObject(target.attr('src'))){
                    return false;
                }
                var left = parseFloat(target.css('left'));
                var top = parseFloat(target.css('top'));
                var new_left,new_top;
                left = left === null ? 0 : left;
                top = top === null ? 0 : top;
                var e = getEdge(p_zoom);
                var isRemove = false;
                if(left < e.minLeft){
                    new_left = e.minLeft;
                    isRemove = true;
                }
                else if(left >= e.maxLeft){
                    new_left = e.maxLeft;
                    isRemove = true;
                }
                if(top < e.minTop){
                    new_top = e.minTop;
                    isRemove = true;
                }
                else if(top >= e.maxTop){
                    new_top = e.maxTop;
                    isRemove = true;
                }
                if(isRemove){
                    var prop = {
                        'left': new_left,
                        'top': new_top
                    };
                    prop = $.extend(prop,p_zoom);
                    ajust(prop);
                }    
            }
            function checkSize(){
                if($.isEmptyObject(target.attr('src'))){
                    return false;
                }
                var e = getSize();
                var newWidth;
                var isRezoom = false;
                if(e.tgtWidth < e.tgtHeight){
                    if(e.tgtWidth < e.cutWidth){
                        newWidth = e.cutWidth;
                        isRezoom = true;
                    }
                }
                else{
                    if(e.tgtHeight < e.cutHeihgt){
                        newWidth = e.cutHeihgt / e.tgtHeight * e.tgtWidth;
                        isRezoom = true;
                    }        
                }
                if(isRezoom){
                    var prop = {
                        'width':newWidth
                    };
                    return prop;
                }
                return null;
                //limit in checkEdge
            }
            function getEdge(p_zoom){
                var e = getSize();
                //调整尺寸值 - 开始
                //如果源图片有尺寸缩放动作等待，则调整尺寸值为缩放后的尺寸，避免尺寸的问题导致图片调整不正确
                var t_w = p_zoom ? p_zoom.width : e.tgtWidth;
                var t_h = p_zoom ? p_zoom.width * e.tgtHeight / e.tgtWidth : e.tgtHeight;
                //调整尺寸值 - 结束
                var e_l = e.cutWidth - t_w;
                var e_t = e.cutHeihgt - t_h;
                var lm_offset = limiter.offset();
                var tc_offset = target_container.offset();
                var tc_shift_left = parseFloat(target_container.css('borderLeftWidth'));
                var tc_shift_top = parseFloat(target_container.css('borderTopWidth'));
                var shift_x = lm_offset.left - tc_offset.left + cut_shift_left - tc_shift_left;
                var shift_y = lm_offset.top - tc_offset.top + cut_shift_top - tc_shift_top;
                var ret = {
                    'maxLeft': 0 + shift_x,//左边界
                    'maxTop': 0 + shift_y,//上边界
                    'minLeft': e_l + shift_x,//右边界
                    'minTop': e_t + shift_y//下边界
                 };
                 return ret;
            }
            function getSize(){//获取mask和image的尺寸信息
                var lw = limiter.width();
                var lh = limiter.height();
                var tw = target.width();
                var th = target.height();
                return {
                    'cutWidth': lw,
                    'cutHeihgt': lh,
                    'tgtWidth': tw,
                    'tgtHeight': th
                };
            }
            return {
                listen:listen,
                unlisten:unlisten,
                check:check
            };
        }());
//边缘限制模块 - 结束

//加载模块 - 开始
//描述：当图片加载完成后，自适应窗口（如果需要）并设置剪切窗口的背景图片
        var Loader = (function(){
            var target = null,
                  ajust_delay = 100,
                  cut_frame = null,
                  container = null;
            function listen(tgt,cf,con){
                if(!tgt || !cf || !con){
                    return;
                }
                target = tgt;
                cut_frame = cf;
                container = con;
                target.css('display','none'); //IE下图片未加载状态下有默认图片，隐藏之
                target.bind('load',function(){
                    target.css('display','block');
                    if(options.autoAjust){
                        autoAjust();
                    }
                });
                target.bind('error',function(e){
                    alert('图片加载错误，请保证上传的图片没有超过限制大小（10MB），不要上传有问题的图片。');
                    target.removeAttr('src');
                });
            }
            function autoAjust(){
                var padding = 5;//px
                var tgt_w = target.width();
                var tgt_h = target.height();
                var con_w = container.width();
                var con_h = container.height();
                var to_w = con_w - 2 * padding;
                var to_h = con_h - 2 * padding;
                var new_w,new_l,new_t;
                if(tgt_w > tgt_h){
                    new_w = to_w;
                    new_l = -(new_w -con_w) / 2;
                    new_t = -((to_w / tgt_w) * tgt_h - con_h) / 2;
                }
                else{
                    new_w = tgt_w * to_h / tgt_h;
                    new_l = -(new_w -con_w) / 2;
                    new_t = -(to_h - con_h) / 2;
                }
                var prop ={
                    'left': new_l,
                    'top': new_t,
                    'width': new_w
                };
                ajust(prop);
            }
            function ajust(prop){
                applyCss(target,prop,true,null,null,ajust_delay);
            }
            return {
                listen: listen,
                ajust: autoAjust
            };
        }());
        function createDiv(){
            var cutter_id = myId(nextId++);
            src_img = $(obj);
            src_img
                  .addClass(myClass('src-img'))
                  .wrap('<div class="' + myClass('container') + '" jcutter-id="' + cutter_id + '" />')
                  .parent()
                  .append('<div class="' + myClass('cut-frame') + '" />')
                  .append('<div class="' + myClass('mask-left') + ' ' + myClass('container-mask') + '">')
                  .append('<div class="' + myClass('mask-top') + ' ' + myClass('container-mask') + '">')
                  .append('<div class="' + myClass('mask-right') + ' ' + myClass('container-mask') + '">')
                  .append('<div class="' + myClass('mask-bottom') + ' ' + myClass('container-mask') + '">');
        }
        function applyOptions(){
            cut_frame = src_img.siblings(myJClass('cut-frame'));
            var w = options.width,
                  h = options.height,
                  cs = options.css;
          
            var mask_left = src_img.siblings(myJClass('mask-left')),
                  mask_top = src_img.siblings(myJClass('mask-top')),
                  mask_right = src_img.siblings(myJClass('mask-right')),
                  mask_bottom = src_img.siblings(myJClass('mask-bottom')),
                  masks = src_img.siblings(myJClass('container-mask')),
                  cw = options.cutWidth,
                  ch = options.cutHeight,
                  ccs = options.cutCss;

            cut_frame
                 .width(cw)
                 .height(ch)
                 .css(ccs);

            container = src_img.parent(myJClass('container'));
            container
                  .css(cs)
                  .width(w)
                  .height(h);
          
            var con_w = container.width(),
                  con_h = container.height(),
                  cut_iw = cut_frame.width(),//padding始终为0，所以innerWidth 和width相等
                  cut_ih = cut_frame.height(),
                  cut_bl_w = parseFloat(cut_frame.css('borderLeftWidth')),
                  cut_bt_w = parseFloat(cut_frame.css('borderTopWidth')),
                  cut_br_w = parseFloat(cut_frame.css('borderRightWidth')),
                  cut_bb_w = parseFloat(cut_frame.css('borderBottomWidth')),
                  cut_w = cut_iw + cut_bl_w + cut_br_w,
                  cut_h = cut_ih + cut_bt_w + cut_bb_w;
                  ccs.left = (w - cw) / 2 - cut_bl_w;
                  ccs.top = (h - ch) / 2 - cut_bt_w;
            cut_shift_left = cut_bl_w;
            cut_shift_top = cut_bt_w;
            
            cut_frame.css({
                  'left':ccs.left,
                  'top':ccs.top
            });

            mask_left.css({
                  'position': 'absolute',
                  'left': '0',
                  'top': '0',
                  'width': (con_w-cut_w)/2,
                  'height': con_h
            });
            mask_top.css({
                  'position': 'absolute',
                  'left': (con_w-cut_w)/2,
                  'top': '0',
                  'width': cut_w,
                  'height': (con_h-cut_h)/2
            }); 
            mask_right.css({
                  'position': 'absolute',
                  'left': ccs.left + cut_w,
                  'top': '0',
                  'width': (con_w-cut_w)/2,
                  'height': con_h
            }); 
            mask_bottom.css({
                  'position': 'absolute',
                  'left': (con_w-cut_w)/2,
                  'bottom': '0',
                  'width': cut_w,
                  'height': (con_h-cut_h)/2
            }); 
            masks.css({
                  'opacity': options.maskOpacity,
                  'filter': 'alpha(opacity=' + options.maskOpacity * 100 + ')',
                  'backgroundColor': options.maskColor,
                  'z-index': 10001
            });

            var mListen = $();
            mListen.push(container[0]);
            mListen.push($(myJClass('cut-frame'),container)[0]);

            Mouser.listen(mListen);//以容器窗口和截取窗口创建操作面板
            Dragger.listen(src_img,Mouser);//在操作面板上创建拖拽模块
            Toucher.listen(src_img,Mouser);
            Zoomer.listen(src_img,Mouser);//在操作面板上创建缩放模块
            Loader.listen(src_img,cut_frame,container);
            if(options.limitEdge){
                var dragEndCallback = BorderLimiter.check,
                      zoomEndCallback = dragEndCallback;
                BorderLimiter.listen(src_img,cut_frame,container);//创建边缘限制模块
                Dragger.setOptions({'dragEnd':dragEndCallback});//边缘限制模块监听拖拽完成事件
                Zoomer.setOptions({'zoomEnd':zoomEndCallback});//边缘限制模块监听缩放完成事件
                Toucher.setOptions({'moveEnd':zoomEndCallback});
            }
            else{
                BorderLimiter.unlisten();//创建边缘限制模块
                Dragger.setOptions({'dragEnd':null});//边缘限制模块监听拖拽完成事件
                Zoomer.setOptions({'zoomEnd':null});//边缘限制模块监听缩放完成事件                
            }
            
            return {
                'success':'success'
            };
        }
        function checkOptions(opt){
            var tmpOptions = $.extend(true,{},options,opt,$.jCutter.fixedDefaults);
            if(tmpOptions.width < tmpOptions.cutWidth || tmpOptions.height < tmpOptions.cutHeight){
                return err('剪切尺寸大于插件容器尺寸');
            }
            if(tmpOptions.zoomPercent <= 0 || tmpOptions.zoomPercent >= 1){
                return err('缩放取值范围 (0,1)');
            }
            if(tmpOptions.width <= 0 || tmpOptions.height <= 0){
                return err('插件的高度或宽度不能为0');
            }
            if(tmpOptions.cutWidth <= 0 || tmpOptions.cutHeight <= 0){
                return err('截取的高度或宽度不能为0');
            }
            if(tmpOptions.maskOpacity <= 0 || tmpOptions.maskOpacity > 1){
                return err('缩放取值范围 (0,1]');
            }
            return true;
        }
//初始化  - 开始
        function init(){
            var chk = setOptions();
            if(chk !== true){
                return chk;
            }
            createDiv();
            chk = applyOptions();
            var api = {
                setOptions: setOptionsNew
            };
            src_img.data('jcutter',api);
            return chk;
        }
        return init();
    };
//初始化  - 结束
    $.fn.jCutter = function(opt,callback){
        this.each(function(){
            var ret;
            if($(this).data('jcutter')){
                ret = $(this).data('jcutter').setOptions(opt);
            }
            else{
                ret = $.jCutter(this,opt);
            }        
            if($.isFunction(callback)){
                callback.call(this,ret);
            }
        });
        
        //return this;保持jQuery的链性
        return this;
    };
    //长宽度单位：px(像素)
    $.jCutter.defaults = {
        //基本设置
        autoAjust: true,//自动调整
        limitEdge: true,//限制边缘
        maskOpacity: 0.6,//背景透明度
        maskColor: 'black',
        zoomPercent: 0.3,//缩放比0<zoomPercent<1
        //窗口设置
        width:600,//窗口宽度
        height:450,//窗口高度
        css:{//窗口默认样式
            'position': 'relative',
            'margin': 'auto',
            'boxShadow': '0px 0px 0px',
            'color': 'black',
            'backgroundColor': 'rgb(100,100,100)',
            'borderRadius': '0px',
            'border': 'solid 1px gray',
            'overflow': 'hidden',
            'z-index':10000
        },
        //截取框设置
        cutWidth:200,//截取框宽度
        cutHeight:200,//截取框高度
        cutCss:{//截取框默认样式
            'position':'absolute',
            'boxShadow': '0px 0px 0px',
            'color': 'black',
            'border': 'solid 2px white',
            'z-index': 10002
        },
        //消息映射
        cutChange:function(){}//剪切信息改变
    };
    $.jCutter.fixedDefaults = {
        baseClass: 'jcutter',//基类名
        baseId: 'jcutter_id',//基id名
        css:{//窗口固定样式
            'position': 'relative',
            'margin': 'auto',
            'padding': '0',
            'overflow': 'hidden',
            'z-index':10000
        },
        cutCss:{//截取框固定样式
            'position':'absolute',
            'borderRadius': '0',
            'padding': '0',
            'z-index': 10002
        },
        tgtCss:{//目标图片样式
            'border': 'none',
            'padding': '0',
            'margin': '0'
        }
    };
}(jQuery));